#include "TesAABB3.h"
#include "assert.h"
#include"TesPlane.h"
#include "TesRay.h"

TesAABB3::TesAABB3(TesVector3& Min, TesVector3& Max) {
	this->Max = Max;
	this->Min = Min;
}

void TesAABB3::empty() {
	float Temp = 1e37f;
	Min.x = Min.y = Min.z = Temp;
	Max.x = Max.y = Max.z = -Temp;
}
void TesAABB3::add(TesVector3& pt) {
	if (pt.x <= Min.x)
		Min.x = pt.x;
	else if (pt.x > Max.x)
		Max.x = pt.x;

	if (pt.y <= Min.y)
		Min.y = pt.y;
	else if (pt.y > Max.y)
		Max.y = pt.y;

	if (pt.z <= Min.z)
		Min.z = pt.z;
	else if (pt.z > Max.z)
		Max.z = pt.z;
}

void TesAABB3::create(TesVector3* Pos, int n) {
	assert(Pos && n > 3);
	for (int i = 0; i < n; ++i)
		add(Pos[i]);
}

TesAABB3::TesAABB3(TesVector3* Pos, int n) {
	create(Pos, n);
}

TesVector3 TesAABB3::getCenter() {
	return .5f * (Max - Min);
}

float TesAABB3::getS() {
	return (Max - Min).Length();
}

float TesAABB3::getR() {
	return .5f * getS();
}

TesVector3 TesAABB3::getNearestPoint(TesVector3& Point) {
	TesVector3 Temp;
	Temp.Zero();

	//x
	if (Point.x > Max.x)
		Temp.x = Max.x;
	else if(Point.x < Min.x)
		Temp.x = Min.x;
	else Temp.x = Point.x;

	//y
	if (Point.y > Max.y)
		Temp.y = Max.y;
	else if (Point.y < Min.y)
		Temp.y = Min.y;
	else Temp.y = Point.y;

	//z
	if (Point.z > Max.z)
		Temp.z = Max.z;
	else if (Point.z < Min.z)
		Temp.z = Min.z;
	else Temp.z = Point.z;

	return Temp;
}

bool TesAABB3::checkPtIn(TesVector3& Point) {
	if (Point.x < Min.x || Point.x > Max.x ||
		Point.y < Min.y || Point.y > Max.y ||
		Point.z < Min.z || Point.z > Max.z 
		)
		return false;
	return true;
}

bool TesAABB3::Collide(TesPlane& Plane) {

	TesVector3 TempMin;
	assert(!(Plane.Normal.x == .0f && Plane.Normal.y == .0f && Plane.Normal.z == .0f));

	if (Plane.Normal.x >= .0f)
		TempMin.x = Min.x;
	else
		TempMin.x = Max.x;
	if (Plane.Normal.y >= .0f)
		TempMin.y = Min.y;
	else
		TempMin.y = Max.y;
	if (Plane.Normal.z >= .0f)
		TempMin.z = Min.z;
	else
		TempMin.z = Max.z;

	float NumTemp = TempMin * Plane.Normal;
	return (NumTemp > Plane.d);
}

bool TesAABB3::Collide(TesPlane& Plane, TesVector3& V, TesVector3* hitPos) {
	TesVector3 TempMin;
	TesVector3 TempMax;
	assert(!(Plane.Normal.x == .0f && Plane.Normal.y == .0f && Plane.Normal.z == .0f));

	if (Plane.Normal.x >= .0f)
	{
		TempMin.x = Min.x;
		TempMax.x = Max.x;
	}
	else
	{
		TempMin.x = Max.x;
		TempMax.x = Min.x;
	}
	if (Plane.Normal.y >= .0f)
	{
		TempMin.y = Min.y;
		TempMax.y = Max.y;
	}
	else
	{
		TempMin.y = Max.y;
		TempMax.y = Min.y;
	}
	if (Plane.Normal.z >= .0f)
	{
		TempMin.z = Min.z;
		TempMax.z = Max.z;
	}
	else
	{
		TempMin.z = Max.z;
		TempMax.z = Min.z;
	}

	TesVector3* TempOrg;
	if (TempMin * Plane.Normal > TempMax * Plane.Normal)
		TempOrg = &TempMax;
	else
		TempOrg = &TempMin;

	TesRay Ray(*TempOrg, V);
	return Ray.Collide(Plane, hitPos);
}